//
//  ZZPopMenu.m
//  ZZPopMenu
//
//  Created by 科大 on 2024/2/26.
//

#import "ZZPopMenu.h"
#import "ZZPopMenuCell.h"
#import <Masonry/Masonry.h>

@interface ZZPopMenu()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
/// 箭头
@property (nonatomic, strong) UIView *arrowView;
/// 内部视图
@property (nonatomic, strong) UIView *contentView;
/// 目标视图
@property (nonatomic, weak) UIView *targetView;
/// 方向
@property (nonatomic, assign) ZZMenuDirection direction;
/// 标题数组
@property (nonatomic, copy) NSArray<ZZPopMenuItem *> *titles;
/// 点击
@property (nonatomic, copy) ZZPopMenuClick click;
/// 取消
@property (nonatomic, copy) ZZPopMenuCancel cancel;
/// 列表
@property (nonatomic, strong) UICollectionView *collectionView;
/// 布局
@property (nonatomic, strong) UICollectionViewFlowLayout *layout;
/// 宽度
@property (nonatomic, assign) CGFloat maxWidth;
@end

@implementation ZZPopMenu

+ (void)showBy:(UIView *)view direction:(ZZMenuDirection)direction items:(NSArray<ZZPopMenuItem *> *)items click:(ZZPopMenuClick)click cancel:(ZZPopMenuCancel)cancel {
    if (!view) {
        return;
    }
    ZZPopMenu *menu = [[ZZPopMenu alloc] init];
    menu.modalPresentationStyle = UIModalPresentationOverFullScreen;
    menu.targetView = view;
    menu.direction = direction;
    menu.titles = items;
    menu.click = click;
    menu.cancel = cancel;
    [[self topVC] presentViewController:menu animated:NO completion:nil];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect frame = [self.targetView convertRect:self.targetView.bounds toView:[UIApplication sharedApplication].keyWindow];
    CGFloat targetCenter = frame.origin.x + frame.size.width / 2.0;
    CGFloat width = 0;
    CGFloat height = ZLLineHeight;
    if (self.direction == ZZMenuDirectionHorizontal) {
        width = 10;
        for (ZZPopMenuItem *item in self.titles) {
            width += ([item itemSize].width + 10);
        }
        width = MIN(width, [UIScreen mainScreen].bounds.size.width - 10);
        self.layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        self.layout.minimumInteritemSpacing = 10;
    } else {
        for (ZZPopMenuItem *item in self.titles) {
            width = MAX([item itemSize].width, width);
        }
        self.maxWidth = width;
        width = width + 20;
        height = MIN(height * self.titles.count, [UIScreen mainScreen].bounds.size.height - CGRectGetMaxY(frame) - 50);
        self.layout.scrollDirection = UICollectionViewScrollDirectionVertical;
        self.layout.minimumInteritemSpacing = 0;
    }
    CGFloat left = targetCenter - width / 2.0;
    if ((left + width) > [UIScreen mainScreen].bounds.size.width - 5) {
        left = [UIScreen mainScreen].bounds.size.width - width - 5;
    } else if (left < 5) {
        left = 5;
    }
    [self.view addSubview:self.arrowView];
    [self.view addSubview:self.contentView];
    [self.arrowView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(CGRectGetMidX(frame) - self.arrowView.bounds.size.width / 2.0);
        make.top.mas_equalTo(CGRectGetMaxY(frame));
        make.width.mas_equalTo(12);
        make.height.mas_equalTo(6);
    }];
    [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.arrowView.mas_bottom);
        make.left.mas_equalTo(left);
        make.width.mas_equalTo(width);
    }];
    [self.contentView addSubview:self.collectionView];
    [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(UIEdgeInsetsZero);
        make.height.mas_equalTo(height);
    }];
    [self.collectionView reloadData];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    UITouch *touch = touches.anyObject;
    CGPoint touchPoint = [touch locationInView:self.view];
    if (CGRectContainsPoint(self.contentView.frame, touchPoint)) {
        [super touchesBegan:touches withEvent:event];
        return;
    }
    [self dismissViewControllerAnimated:NO completion:nil];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (self.cancel) {
            self.cancel();
        }
    });
}

#pragma mark - delegate

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    ZZPopMenuItem *item = self.titles[indexPath.row];
    if (self.direction == ZZMenuDirectionVertical) {
        return CGSizeMake(self.maxWidth, [item itemSize].height);
    }
    return [item itemSize];
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.titles.count;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    ZZPopMenuCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"ZZPopMenuCell" forIndexPath:indexPath];
    ZZPopMenuItem *item = self.titles[indexPath.row];
    cell.titleLabel.text = item.title;
    cell.titleLabel.font = item.font;
    cell.titleLabel.textColor = item.color;
    if (self.direction == ZZMenuDirectionHorizontal) {
        cell.titleLabel.textAlignment = NSTextAlignmentCenter;
    } else {
        cell.titleLabel.textAlignment = NSTextAlignmentLeft;
    }
    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    [self dismissViewControllerAnimated:NO completion:nil];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (self.click) {
            self.click(indexPath.row);
        }
    });
}

#pragma mark - init

- (UIView *)arrowView {
    if (!_arrowView) {
        _arrowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 12, 6)];
        CAShapeLayer *subLayer = [CAShapeLayer layer];
        subLayer.frame = _arrowView.bounds;
        [subLayer setFillColor:[self colorWithString:@"4C4C4C"].CGColor];
        UIBezierPath *path = [UIBezierPath bezierPath];
        
        CGPoint point1 = CGPointMake(0, 6);
        CGPoint point2 = CGPointMake(6, 0);
        CGPoint point3 = CGPointMake(12, 6);
        [path moveToPoint:point1];
        [path addLineToPoint:point2];
        [path addLineToPoint:point3];
        [path moveToPoint:point1];
        subLayer.path = path.CGPath;
        [_arrowView.layer insertSublayer:subLayer atIndex:0];
    }
    return _arrowView;
}

- (UIView *)contentView {
    if (!_contentView) {
        _contentView = [[UIView alloc] initWithFrame:CGRectZero];
        _contentView.backgroundColor = [self colorWithString:@"4C4C4C"];
        _contentView.layer.cornerRadius = 5;
        _contentView.layer.masksToBounds = YES;
    }
    return _contentView;
}

- (UICollectionView *)collectionView {
    if (!_collectionView) {
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.layout];
        _collectionView.backgroundColor = [UIColor clearColor];
        _collectionView.showsVerticalScrollIndicator = NO;
        _collectionView.showsHorizontalScrollIndicator = NO;
        _collectionView.delegate = self;
        _collectionView.dataSource = self;
        _collectionView.contentInset = UIEdgeInsetsMake(0, 10, 0, 10);
        [_collectionView registerClass:[ZZPopMenuCell class] forCellWithReuseIdentifier:@"ZZPopMenuCell"];
    }
    return _collectionView;
}

- (UICollectionViewFlowLayout *)layout {
    if (!_layout) {
        _layout = [[UICollectionViewFlowLayout alloc] init];
        _layout.itemSize = CGSizeMake(60, 40);
        _layout.minimumLineSpacing = 0;
        _layout.minimumInteritemSpacing = 0;
    }
    return _layout;
}

- (UIColor *)colorWithString:(NSString *)color {
    NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
    if ([cString length] < 6) {
        return [UIColor clearColor];
    }
    if ([cString hasPrefix:@"0X"])
        cString = [cString substringFromIndex:2];
    if ([cString hasPrefix:@"#"])
        cString = [cString substringFromIndex:1];
    if ([cString length] != 6)
        return [UIColor clearColor];
    NSRange range;
    range.location = 0;
    range.length = 2;
    NSString *rString = [cString substringWithRange:range];
    range.location = 2;
    NSString *gString = [cString substringWithRange:range];
    range.location = 4;
    NSString *bString = [cString substringWithRange:range];
    unsigned int r, g, b;
    [[NSScanner scannerWithString:rString] scanHexInt:&r];
    [[NSScanner scannerWithString:gString] scanHexInt:&g];
    [[NSScanner scannerWithString:bString] scanHexInt:&b];
    return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f];
}

+ (UIViewController *)topVC {
    UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
    return [self topViewControllerWithRootViewController:rootViewController];
}

+ (UIViewController *)topViewControllerWithRootViewController:(UIViewController *)rootViewController {
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController *tabBarController = (UITabBarController *)rootViewController;
        return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
    } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController *navigationController = (UINavigationController *)rootViewController;
        return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
    } else if (rootViewController.presentedViewController) {
        UIViewController *presentedViewController = rootViewController.presentedViewController;
        return [self topViewControllerWithRootViewController:presentedViewController];
    } else {
        return rootViewController;
    }
}

@end
